{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Tuple\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.cluster import KMeans\n",
    "from sklearn.metrics import silhouette_score\n",
    "np.random.seed(42)\n",
    "\n",
    "def read_data(filename: str) -> np.ndarray:\n",
    "    \"\"\"读取数据文件并转换为numpy数组\"\"\"\n",
    "    return np.loadtxt(filename)\n",
    "\n",
    "def train_kmeans(X: np.ndarray, n_clusters: int) -> KMeans:\n",
    "    \"\"\"训练K-means模型\"\"\"\n",
    "    model = KMeans(n_clusters=n_clusters, \n",
    "                   n_init='auto',  # 消除版本警告\n",
    "                   random_state=42)\n",
    "    model.fit(X)\n",
    "    return model\n",
    "\n",
    "def calculate_silhouette_score(X: np.ndarray, labels: np.ndarray) -> float:\n",
    "    \"\"\"计算轮廓系数\"\"\"\n",
    "    return silhouette_score(X, labels)\n",
    "\n",
    "def find_best_k(X: np.ndarray, min_k: int = 2, max_k: int = 6) -> Tuple[int, KMeans, float]:\n",
    "    \"\"\"寻找最佳K值\"\"\"\n",
    "    best_score = -1\n",
    "    best_k = min_k\n",
    "    best_model = None\n",
    "    # 遍历从min_k到max_k的每一个整数\n",
    "    for k in range(min_k, max_k + 1):\n",
    "        model = train_kmeans(X, k)# 使用给定的X和k值训练KMeans模型\n",
    "        labels = model.labels_# 获取KMeans模型的标签\n",
    "        score = calculate_silhouette_score(X, labels)# 计算轮廓系数\n",
    "        \n",
    "        if score > best_score: # 如果当前轮廓系数大于最佳轮廓系数\n",
    "            best_score = score # 更新最佳轮廓系数\n",
    "            best_k = k # 更新最佳K值\n",
    "            best_model = model # 更新最佳模型\n",
    "            \n",
    "    return best_k, best_model, best_score\n",
    "\n",
    "def main() -> None:\n",
    "    X = read_data('data.txt')\n",
    "    best_n, best_model, max_score = find_best_k(X)\n",
    "    print(f\"最佳轮廓系数：{max_score:.4f}\")\n",
    "    print(f\"最佳 K 值：{best_n}\")\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
